package field

//FieldType 代表日志字段类型
type FieldType uint

const (
	UnknownType FieldType = 0
	BoolType    FieldType = 1
	Int64Type   FieldType = 2
	Float64Type FieldType = 3
	StringType  FieldType = 4
	ObjectType  FieldType = 5
)

//Field 代表日志字段的接口
type Field interface {
	Name() string
	Type() FieldType
	Value() interface{}
}

//boolField 拥有bool类型的值的日志字段
type boolField struct {
	name      string
	fieldType FieldType
	value     bool
}

func (f *boolField) Name() string {
	return f.name
}

func (f *boolField) Type() FieldType {
	return f.fieldType
}

func (f *boolField) Value() interface{} {
	return f.value
}

func Bool(name string, value bool) Field {
	return &boolField{name: name, fieldType: BoolType, value: value}
}

//int64Field 拥有int64类型的值的日志字段
type int64Field struct {
	name      string
	fieldType FieldType
	value     int64
}

func (f *int64Field) Name() string {
	return f.name
}

func (f *int64Field) Type() FieldType {
	return f.fieldType
}

func (f *int64Field) Value() interface{} {
	return f.value
}

func Int64(name string, value int64) Field {
	return &int64Field{name: name, fieldType: Int64Type, value: value}
}

//float64Field 拥有float64类型的值的日志字段
type float64Field struct {
	name      string
	fieldType FieldType
	value     float64
}

func (f *float64Field) Name() string {
	return f.name
}

func (f *float64Field) Type() FieldType {
	return f.fieldType
}

func (f *float64Field) Value() interface{} {
	return f.value
}

func Float64(name string, value float64) Field {
	return &float64Field{name: name, fieldType: Float64Type, value: value}
}

//stringField 拥有string类型的值的日志字段
type stringField struct {
	name      string
	fieldType FieldType
	value     string
}

func (f *stringField) Name() string {
	return f.name
}

func (f *stringField) Type() FieldType {
	return f.fieldType
}

func (f *stringField) Value() interface{} {
	return f.value
}

func String(name string, value string) Field {
	return &stringField{name: name, fieldType: StringType, value: value}
}

//objectField 拥有interface{}类型的值的日志字段
type objectField struct {
	name      string
	fieldType FieldType
	value     interface{}
}

func (f *objectField) Name() string {
	return f.name
}

func (f *objectField) Type() FieldType {
	return f.fieldType
}

func (f *objectField) Value() interface{} {
	return f.value
}

func Object(name string, value interface{}) Field {
	return &objectField{name: name, fieldType: ObjectType, value: value}
}
